/*----------------------------------------------------------
* FILE: JasperHelper.java
* LOGICAL NAME: JasperHelper
* PRODUCT: bila-framework
*----------------------------------------------------------
* MODIFICATIONS
* DATE Oct 10, 2011
* AUTHOR wjuarez
*----------------------------------------------------------
*/

package bila.framework.reports.jasper;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRXmlDataSource;
import net.sf.jasperreports.engine.util.JRLoader;
import bila.framework.commons.Constants;

/**
 * @author WJuarez
 * <b>Created by </b>wjuarez
 * <b>for</b> bila-framework
 * <b>package</b> bila.framework.reports.jasper
 * <b>on</b> Oct 10, 2011 10:01:31 PM
 * <b>Purpose</b> 
 * <p>
 *		Funciones de apoyo para la generacion de reportes
 * </p>
 */
public class JasperHelper extends JasperFormat {

	/**
	 * Genera el reporte ocupando como datasource un objeto JDBC Connection
	 * @param request HttpServletRequest
	 * @param response HttpServletResponse
	 * @param reportParameters Parametros del reporte
	 * @param nameReport Ruta y nombre del reporte
	 * @param type Formato en que se generara el reporte
	 * @param con Objeto con la conexion a la base de datos
	 * @param nameReportFile nombre del archivo generado por Jasper
	 * @throws Exception
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected void generateReportFromJdbc(HttpServletRequest request, HttpServletResponse response, HashMap reportParameters, String nameReport, String type, Connection con, String nameReportFile) throws Exception {
		try{
			HashMap<String, String> parameters = getAllParameters(reportParameters);
			JasperReport jasperReport = (JasperReport) JRLoader.loadObject(nameReport);
			JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, con);
			generateReport(request, response, jasperPrint, type, nameReportFile);
			disconnect(con);
		}catch(Exception e){
			e.printStackTrace();
			disconnect(con);
			throw e;
		}
	}
	
	/**
	 * Genera el reporte ocupando como datasource un XML
	 * @param request HttpServletRequest
	 * @param response HttpServletResponse
	 * @param reportParameters Parametros del reporte
	 * @param nameReport Nombre del reporte
	 * @param type Formato en que se generara el reporte
	 * @param xml String con el XML a utilizar como datasource
	 * @param xpath Definicion de los nodos del XML a utilizar en el reporte
	 * @param nameReportFile nombre del archivo generado por Jasper
	 * @throws Exception
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected void generateReportFromXml(HttpServletRequest request, HttpServletResponse response, HashMap reportParameters, String nameReport, String type, String xml, String xpath, String nameReportFile) throws Exception {
		try{			
			HashMap parameters = getAllParameters(reportParameters);
			JasperReport jasperReport = (JasperReport) JRLoader.loadObject(nameReport);
			JRXmlDataSource xmlDataSource = new JRXmlDataSource(parseStringToIS(xml), xpath);
			JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, xmlDataSource);			
			generateReport(request, response, jasperPrint, type, nameReportFile);
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * Recupera los parametros generales del reporte mas los parametros que se envian
	 * @param reportParameters parametros propios del reporte
	 * @return todos los parametros que poseera el reporte
	 * @throws Exception
	 */
	private HashMap<String, String> getAllParameters(HashMap<String, String> reportParameters) throws Exception{
		HashMap<String, String> parameters =  new HashMap<String, String>();
		parameters.putAll(reportParameters);
		return parameters;
	}
	
	/**
	 * Se genera el reporte segun el formato deseado
	 * @param request HttpServletRequest
	 * @param response HttpServletResponse
	 * @param jasperPrint Objeto jasper a imprimir
	 * @param type Formato del reporte
	 * @param nameReport nombre del archivo del reporte
	 * @throws Exception
	 */
	private void generateReport(HttpServletRequest request, HttpServletResponse response, JasperPrint jasperPrint, String type, String nameReport) throws Exception{
		if(type.equals(Constants.REPORT_PDF))
			generatePdfReport(response, jasperPrint, nameReport);
		if(type.equals(Constants.REPORT_EXCEL))
			generateXlsReport(response, jasperPrint, nameReport);
		else if(type.equals(Constants.REPORT_CSV))
			generateCsvReport(response, jasperPrint, nameReport);
		else if(type.equals(Constants.REPORT_HTML))
			generateHtmlReport(request, response, jasperPrint);
		else if(type.equals(Constants.REPORT_RTF))
			generateRtfReport(response, jasperPrint, nameReport);		
	}
	
	/**
	 * Cierra la conexion de la base de datos
	 * @param conn
	 */
	private void disconnect(Connection conn) {
		if(conn != null)
			try{
				conn.close();
			}catch(Exception e){
				e.printStackTrace();
				try{
					if(!conn.isClosed())					
						conn.close();
					}catch(Exception ex){
						ex.printStackTrace();
					}
			}
	}
	
	/**
	 * Convierte un String a un InputStream
	 * @param xmlStream String con el formato XML
	 * @return InputStream
	 * @throws Exception
	 */
	private InputStream parseStringToIS(String xmlStream) throws Exception {
		if (xmlStream == null)
			return null;
		xmlStream = xmlStream.trim();
		InputStream in = new ByteArrayInputStream(xmlStream.getBytes("UTF-8"));
		return in;
	}
}
